package cn.kgc.service.impl;

import cn.kgc.base.dto.LockStockDTO;
import cn.kgc.base.vo.OrderItemVo;
import cn.kgc.base.vo.OrderSpuInfoVo;
import cn.kgc.base.vo.UmsMemberReceiveAddressVo;
import cn.kgc.client.CartFeignClient;
import cn.kgc.client.PmsFeignClient;
import cn.kgc.client.UmsFeignClient;
import cn.kgc.client.WmsFeignClient;
import cn.kgc.commons.exception.HttpException;
import cn.kgc.commons.vo.Result;
import cn.kgc.constant.OrderConstant;
import cn.kgc.constant.OrderStatusEnum;
import cn.kgc.constant.SourceTypeEnum;
import cn.kgc.entity.OmsOrder;
import cn.kgc.entity.OmsOrderItem;
import cn.kgc.mapper.OmsOrderItemMapper;
import cn.kgc.mapper.OmsOrderMapper;
import cn.kgc.service.OrderService;
import cn.kgc.vo.OrderSubmitVO;
import com.baomidou.mybatisplus.annotation.IdType;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p></p>
 *
 * @author 李孟鸠
 * @Date: 2023年01月02日14:53
 */
@Service("orderService")
public class OrderServiceImpl  implements OrderService {

    @Resource
    private OmsOrderMapper omsOrderMapper;

    @Resource
    private OmsOrderItemMapper omsOrderItemMapper;

    @Resource
    private CartFeignClient cartFeignClient;

    @Resource
    private UmsFeignClient umsFeignClient;

    @Resource
    private PmsFeignClient pmsFeignClient;

    @Resource
    private WmsFeignClient wmsFeignClient;


//    @GlobalTransactional
    @Transactional
    public String generateOrderInfo(OrderSubmitVO orderSubmitVO,
                                    long memberId,String memberUserName) {
        //保存OmsOrder数据
        OmsOrder omsOrder = getOmsOrder(orderSubmitVO,memberId, memberUserName);
        if(omsOrder==null){
            throw new HttpException(50002,
                    HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
        omsOrderMapper.insert(omsOrder);

        //保存OmsOrderItem数据
        List<OmsOrderItem>  omsOrderItemList= getOmsOrderItem(omsOrder);
        if(omsOrderItemList==null){
            throw new HttpException(50002,
                    HttpStatus.INTERNAL_SERVER_ERROR.value());
        }

        List<LockStockDTO> lockStockDTOList = new ArrayList<>();
        for (OmsOrderItem omsOrderItem : omsOrderItemList) {
            omsOrderItemMapper.insert(omsOrderItem);
            LockStockDTO lockStockDTO=new LockStockDTO();
            lockStockDTO.setAreaCode(omsOrder.getAreaCode());
            lockStockDTO.setSkuId(omsOrderItem.getSkuId());
            lockStockDTO.setLockStock(omsOrderItem.getSkuQuantity());
            lockStockDTO.setOrderSn(omsOrder.getOrderSn()); //订单号
            lockStockDTOList.add(lockStockDTO);
        }
        //锁定库存
        Result<Boolean>  result=wmsFeignClient.lockStock(lockStockDTOList);
        if(result.getData()==false){ //锁库存失败,服务降级
            throw new HttpException(50002,HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
        return omsOrder.getOrderSn();
    }
    /**
     * 获得订单对应的商品的信息
     * @Param omsOrder 订单的信息
     * @return  订单对应的商品的信息
     */
    private List<OmsOrderItem> getOmsOrderItem(OmsOrder omsOrder){
        //购物车中对应的选中的商品
        Result<List<OrderItemVo>> result=
                cartFeignClient.getOrderItemVo(omsOrder.getMemberId());
        if(result.getData()==null){  //服务降级
            return null;
        }
        List<OrderItemVo> orderItemVoList=result.getData();
        //订单商品对应的SPU的数据
        //方式一:获得购物车中每个商品的SpuId,根据SpuId获得SPU的信息
        //(选择)方式二:将购物车中的所有商品的SpuId进行过滤,去掉重复数据。在根据一组SpuId获得Spu的信息
        HashSet<Long> spuIdSet=new HashSet<>();
        for (OrderItemVo orderItemVo : orderItemVoList) {
            spuIdSet.add(orderItemVo.getSpuId());
        }
        Result<Map<Long,OrderSpuInfoVo>> result2=
                pmsFeignClient.getOrderSpuInfo(spuIdSet);
        if(result2.getData()==null){//如果服务降级,返回空的数据
            return null;
        }
        Map<Long,OrderSpuInfoVo> map = result2.getData();
        //购物车中商品对应的订单的商品信息
        List<OmsOrderItem> omsOrderItemList=
                orderItemVoList.stream().map(orderItemVo -> {
                    OmsOrderItem omsOrderItem=new OmsOrderItem();
                    //订单相关的数据
                    omsOrderItem.setOrderSn(omsOrder.getOrderSn());
                    omsOrderItem.setOrderId(omsOrder.getId());
                    //订单的sku的数据
                    omsOrderItem.setSkuId(orderItemVo.getSkuId());
                    omsOrderItem.setSkuName(orderItemVo.getTitle());
                    omsOrderItem.setSkuQuantity(orderItemVo.getCount());
                    omsOrderItem.setSkuPrice(orderItemVo.getPrice());
                    omsOrderItem.setSkuPic(orderItemVo.getImage());
                    //将List集合转为String类型的字符串,集合中的每个元素都使用"-"进行关联
                    String skuAttrsValue =
                            StringUtils.collectionToDelimitedString(orderItemVo.getSkuAttr(),"-");
                    omsOrderItem.setSkuAttrsVals(skuAttrsValue);
                    //订单商品的积分数据(规则引擎 Drools)
                    omsOrderItem.setGiftIntegration(orderItemVo.getTotalPrice().intValue());
                    omsOrderItem.setGiftGrowth(orderItemVo.getTotalPrice().intValue());
                    //封装SPU的信息
                    OrderSpuInfoVo orderSpuInfoVo= map.get(orderItemVo.getSpuId());
                    omsOrderItem.setSpuId(orderSpuInfoVo.getSpuId());
                    omsOrderItem.setSpuName(orderSpuInfoVo.getSpuName());
                    omsOrderItem.setSpuPic(orderSpuInfoVo.getSpuPic());
                    omsOrderItem.setSpuBrand(orderSpuInfoVo.getSpuBrand());
                    omsOrderItem.setCategoryId(orderSpuInfoVo.getCategoryId());
                    return omsOrderItem;
                }).collect(Collectors.toList());
        return omsOrderItemList;
    }

    private OmsOrder getOmsOrder(OrderSubmitVO orderSubmitVO,long memberId,String memberUserName) {
        OmsOrder omsOrder=new OmsOrder();//保存OmsOrder数据
        omsOrder.setMemberId(memberId);//会员ID
        String orderSn= UUID.randomUUID().toString()
                .replaceAll("-","");
        omsOrder.setOrderSn(orderSn);//订单编号
        omsOrder.setMemberUsername(memberUserName); //会员名字

        Result<List<OrderItemVo>> result=
                cartFeignClient.getOrderItemVo(memberId);//获得用户的购物车中的商品信息
        BigDecimal totalPrice = new BigDecimal(0);
        if(result.getData()==null){ //服务降级 获得购物车中商品信息为空
            return null; //订单信息为null
        }
        List<OrderItemVo> orderItemVoList= result.getData();
        for (OrderItemVo orderItemVo : orderItemVoList) {
            totalPrice= totalPrice.add(orderItemVo.getTotalPrice());
        }
        omsOrder.setTotalAmount(totalPrice); //总额
        omsOrder.setPayAmount(totalPrice); //应付金额
        omsOrder.setFreightAmount(new BigDecimal(0));//运费
        omsOrder.setPayType(orderSubmitVO.getPayType().shortValue());//支付方式
        omsOrder.setSourceType(SourceTypeEnum.SOURCE_TYPE_APP.getSourceType()); //订单来源
        omsOrder.setStatus(OrderStatusEnum.NON_PAY.getOrderStatus());//订单状态
        omsOrder.setIntegration(totalPrice.intValue());//积分
        omsOrder.setGrowth(totalPrice.intValue()); //成长值
        //获得收货人的地址信息
        long addRId= orderSubmitVO.getAddrId();
        Result<UmsMemberReceiveAddressVo> result2=
                umsFeignClient.selectOne(addRId);
        if(result2.getData()==null){ //收货人的地址信息服务降级
            return null;
        }
        UmsMemberReceiveAddressVo umsMemberReceiveAddressVo= result2.getData();
        omsOrder.setReceiverName(umsMemberReceiveAddressVo.getName());
        omsOrder.setReceiverPhone(umsMemberReceiveAddressVo.getPhone());
        omsOrder.setReceiverPostCode(umsMemberReceiveAddressVo.getPostCode());
        omsOrder.setReceiverProvince(umsMemberReceiveAddressVo.getProvince());
        omsOrder.setReceiverCity(umsMemberReceiveAddressVo.getCity());
        omsOrder.setReceiverRegion(umsMemberReceiveAddressVo.getRegion());
        omsOrder.setReceiverDetailAddress(umsMemberReceiveAddressVo.getDetailAddress());
        omsOrder.setNote(orderSubmitVO.getNote());
        omsOrder.setAreaCode(umsMemberReceiveAddressVo.getAreacode());
        return omsOrder;
    }
}
